package cn.yangliu.oauth2.config.components;

import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.common.OAuth2RefreshToken;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;
import org.springframework.security.oauth2.provider.token.store.redis.RedisTokenStore;
import org.springframework.security.oauth2.provider.token.store.redis.RedisTokenStoreSerializationStrategy;

import java.util.Collection;
import java.util.Objects;

/**
 * @author 杨柳
 * @date 2019-04-17
 * 装饰器模式 实际干活的是redisTokenStore
 */
public class JwtRedisTokenStore extends JwtTokenStore {

    private RedisTokenStore redisTokenStore;

    public JwtRedisTokenStore(JwtAccessTokenConverter jwtTokenEnhancer,
                               RedisConnectionFactory redisConnectionFactory) {
        this(jwtTokenEnhancer, redisConnectionFactory, null);
    }

    public JwtRedisTokenStore(JwtAccessTokenConverter jwtTokenEnhancer,
                               RedisConnectionFactory redisConnectionFactory,
                               RedisTokenStoreSerializationStrategy strategy) {
        super(jwtTokenEnhancer);
        redisTokenStore = new RedisTokenStore(redisConnectionFactory);
        if (Objects.nonNull(strategy)) {
            redisTokenStore.setSerializationStrategy(strategy);
        }
    }


    @Override
    public void storeAccessToken(OAuth2AccessToken token, OAuth2Authentication authentication) {
        redisTokenStore.storeAccessToken(token, authentication);
    }


    @Override
    public void storeRefreshToken(OAuth2RefreshToken refreshToken, OAuth2Authentication authentication) {
        redisTokenStore.storeRefreshToken(refreshToken, authentication);
    }

    @Override
    public OAuth2Authentication readAuthentication(OAuth2AccessToken token) {
//                redisTemplate
        return redisTokenStore.readAuthentication(token);
    }

    @Override
    public OAuth2Authentication readAuthentication(String token) {
        return redisTokenStore.readAuthentication(token);
    }

    @Override
    public OAuth2AccessToken readAccessToken(String tokenValue) {
        return redisTokenStore.readAccessToken(tokenValue);
    }

    @Override
    public void removeAccessToken(OAuth2AccessToken token) {
        redisTokenStore.removeAccessToken(token);
    }

    @Override
    public OAuth2RefreshToken readRefreshToken(String tokenValue) {
        return redisTokenStore.readRefreshToken(tokenValue);
    }

    @Override
    public OAuth2Authentication readAuthenticationForRefreshToken(OAuth2RefreshToken token) {
        return redisTokenStore.readAuthenticationForRefreshToken(token);
    }

    @Override
    public void removeRefreshToken(OAuth2RefreshToken token) {
        redisTokenStore.removeRefreshToken(token);
    }

    @Override
    public void removeAccessTokenUsingRefreshToken(OAuth2RefreshToken refreshToken) {
        redisTokenStore.removeAccessTokenUsingRefreshToken(refreshToken);
    }

    @Override
    public OAuth2AccessToken getAccessToken(OAuth2Authentication authentication) {
        return redisTokenStore.getAccessToken(authentication);
    }

    @Override
    public Collection<OAuth2AccessToken> findTokensByClientIdAndUserName(String clientId, String userName) {
        return redisTokenStore.findTokensByClientIdAndUserName(clientId, userName);
    }

    @Override
    public Collection<OAuth2AccessToken> findTokensByClientId(String clientId) {
        return redisTokenStore.findTokensByClientId(clientId);
    }

}
